# Copyright (c) 2024, yuxinyong and contributors
# For license information, please see license.txt

import frappe
from frappe import _
from frappe.model.document import Document

class WorkOrderScheduling(Document):

	def on_submit(self):
		self.sync_work_order()

	def on_update_after_submit(self):
		self.sync_total_items()
		self.sync_work_order()

	def sync_work_order(self):		
		for row in self.scheduling_items:
			frappe.db.set_value("Work Order",row.work_order,
				{"custom_work_order_scheduling":row.parent,
				"custom_scheduling_qty":row.scheduling_qty,
				"planned_start_date":row.planned_start_date,
				"planned_end_date":row.planned_end_date,
				"custom_workstation":row.workstation}
			)

	def validate(self):
		self.validate_scheduling_qty()		
		self.get_item_wh_valuation_rate()
		self.sync_total_items()
	
	def get_item_wh_valuation_rate(self):
		warehouse_list = {row.warehouse for row in self.scheduling_items}
		if warehouse_list:		
			bin = frappe.qb.DocType('Bin')
			data = frappe.qb.from_(bin
				).where(bin.item_code.isin({row.item_code for row in self.scheduling_items})
				).where(bin.warehouse.isin(warehouse_list)
				).select(bin.item_code, bin.warehouse, bin.valuation_rate
				).run(as_dict=1)
			item_wh_rate_map = {(row.item_code, row.warehouse): row.valuation_rate for row in data}
			for row in self.scheduling_items:
				row.rate = item_wh_rate_map.get((row.item_code, row.warehouse), 0)
	
	def validate_scheduling_qty(self):
		for row in self.scheduling_items:
			if row.scheduling_qty > row.work_order_qty:
				frappe.throw(_('Row {0} scheduling qty {1} can not be greater than work order qty {2}').format(
					row.idx, row.scheduling_qty, row.work_order_qty
				))

	def sync_total_items(self):	
		grouped = {}
		total_qty = 0
		total_qty1 = 0
		total_amount=0
		name_map = dict(frappe.get_all('Customer',
			filters = {'name': ('in', {item.customer for item in self.scheduling_items})},
			fields = ['name','customer_name'],
			as_list = 1))
		for row in self.scheduling_items:
			row.scheduling_qty = frappe.utils.flt(row.scheduling_qty)
			row.customer_name = name_map.get(row.customer, '')
			row.planned_start_date=frappe.utils.get_datetime(row.planned_start_date)
			row.planned_end_date=frappe.utils.get_datetime(row.planned_end_date)
			workstation = row.workstation
			total_qty1 = total_qty1 + row.scheduling_qty
			qty = row.scheduling_qty*5 if row.item_name and "五" in row.item_name else row.scheduling_qty
			row.amount=frappe.utils.flt(row.rate)*row.scheduling_qty 
			amount=row.amount
			qty_dict = grouped.setdefault(workstation, {'qty':0, 'amount':0})
			qty_dict['qty'] += qty
			qty_dict['amount'] += amount			
		self.total_qty1 = total_qty1   #整包数量
		date = [item.planned_start_date for item in self.scheduling_items]
		self.from_date=min(date)
		self.to_date=max(date)
		self.scheduling_total_items = []
		for workstation, group in grouped.items():
			qty=group['qty']
			amount=group['amount']
			self.append("scheduling_total_items",
				{
					'workstation': workstation,
					'scheduling_total_qty': qty,
					'scheduling_total_amount': amount
				}
			)
			total_qty += qty			
			total_amount += amount			
		self.total_qty = total_qty
		self.total_amount = total_amount

@frappe.whitelist()
def create_work_order_goods_issue():
	docname = frappe.form_dict.get("docname")
	#docname = 'PS24010009'
	doc = frappe.get_doc("Production Scheduling", docname)
	items = self.scheduling_items
	stock_entry_names = []
	posting_date = frappe.utils.today()
	posting_time = frappe.utils.nowtime()
	work_order_data = frappe.get_all('Work Order',
		filters={'name':
			('in', {row.work_order for row in items})
		},
		fields= ['name','use_multi_level_bom','wip_warehouse','bom_no']
	)
	work_order_dict = {row.name:row for row in work_order_data}
	for item in items:
		#参考work_order.py里的make_stock_entry
		work_order_info = work_order_dict.get(item.work_order)
		stock_entry = frappe.get_doc(
			{"doctype": "Stock Entry",
			"purpose": "Material Transfer for Manufacture",
			"work_order": item.work_order,
			"posting_date": posting_date,
			"posting_time": posting_time,
			"company": self.company,
			"from_bom": 1,
		"bom_no": work_order_info.get('bom_no'),
		"use_multi_level_bom": work_order_info.get('use_multi_level_bom'),
			"to_warehouse": work_order_info.get('wip_warehouse'),
			"fg_completed_qty": item.work_qty,
			"custom_work_order_scheduling": docname
			}) 
		stock_entry.set_stock_entry_type()
		stock_entry.get_items()
		stock_entry.insert(ignore_permissions=1)
		stock_entry_names.append(stock_entry.name)
	frappe.msgprint(','.join(stock_entry_names))
	return stock_entry_names

@frappe.whitelist()
def update_work_order_scheduling_status():
	wo = frappe.qb.DocType('Work Order')
	ps = frappe.qb.DocType('Production Scheduling')
	psi = frappe.qb.DocType('Scheduling Item').as_('si')
	frappe.qb.update(psi
		).join(wo
		).on(psi.work_order == wo.name
		).join(ps
		).on(psi.parent == ps.name
		).set(psi.produced_qty, wo.produced_qty
		).where(ps.done == 0
		).run()

	ps_has_open_wo = frappe.qb.from_(psi
		).join(wo
		).on(psi.work_order == wo.name
		).join(ps
		).on(psi.parent == ps.name
		).where(psi.produced_qty < wo.produced_qty
		).where(ps.done == 0
		).select(ps.name
		).distinct(			
		)
	
	frappe.qb.update(ps
		).where(ps.done == 0
		).where(ps.name.notin(ps_has_open_wo)
		).set(ps.done, 1
		).run()
